<?php

namespace app\common\logic;

use app\common\library\exception\ApiException;
use app\common\library\Helper\DateTime;
use app\common\library\TencentMap;
use app\common\model\Images;
use app\common\model\Order;
use app\common\model\Shop;
use app\common\model\Tag;
use app\common\resourceHandle\ShopResource;
use Carbon\Carbon;
use think\db\Query;
use app\common\library\Helper\Arr;

class ShopLogic extends BaseLogic
{
    public $model;

    public $resourceHandle;

    public function assignModel()
    {
        $this->model          = new Shop();
        $this->resourceHandle = new ShopResource();
    }

    /**
     * 搜索条件处理
     * @param Query $query
     * @param array $params
     * @return Query
     */
    public function handleSearch(Query $query, array $params): Query
    {
        if (isset($params['status']) && $params['status'] !== '') {
            $query->where('s.status', $params['status']);
        }
        if (isset($params['shop_name'])) {
            $query->where('s.shop_name', 'like', "%" . $params['shop_name'] . "%");
        }
        $query->with(['shopGoods' => function ($query) {
            $query->field('id,goods_id,shop_id,price')->with(['goods']);
        }]);
        if (!empty($params['business_time'])) {
            $nowTime = date('H:i');
            $week    = Carbon::now()->weekday();
            if ((int)$params['business_time'] === 1) { // 营业
                $query->where('s.business_start_time', '<=', $nowTime)
                    ->where('s.business_end_time', '>', $nowTime)
                    ->where('s.business_week', 'like', '%' . $week . '%');
            } else { // 休息
                $query->where('s.business_start_time', '>', $nowTime)
                    ->whereOr('s.business_end_time', '<=', $nowTime)
                    ->whereOr('s.business_week', 'not like', '%' . $week . '%');
            }
        }

        if (!empty($params['city'])) {
            $query->where('city', $params['city']);
        }

        return $query;
    }

    /**
     * 商家分页列表
     * @param array $params
     * @return array
     * @throws \think\exception\DbException
     */
    public function index(array $params): array
    {
        $params['status'] = $this->enable;
        $subSql           = Order::where('order_status', '>', 0)->fieldRaw('count(id) as sale_num, shop_id')->group('shop_id')->buildSql();
        // 排序
        if (isset($params['sort']) && $params['sort'] === 'sales') {
            $query = $this->model->alias('s')
                ->join([$subSql => 'o'], 's.id = o.shop_id', 'LEFT')
                ->order('o.sale_num desc');
        } elseif (isset($params['sort']) && $params['sort'] === 'distance') {
            $query = $this->model->alias('s')
                ->field("s.*,(6378.138 * 2 * asin(sqrt(pow(sin((latitude * pi() / 180 - " . $params['lat'] . " * pi() / 180) / 2),2) + cos(latitude * pi() / 180) * cos(" . $params['lat'] . " * pi() / 180) * pow(sin((longitude * pi() / 180 - " . $params['lng'] . " * pi() / 180) / 2),2))) * 1000) as distance")
                ->join([$subSql => 'o'], 's.id = o.shop_id', 'LEFT')
                ->order('distance asc');
        } else {
            $query = $this->model->alias('s')
                ->join([$subSql => 'o'], 's.id = o.shop_id', 'LEFT')
                ->order('s.' . $params['sort'] . ' desc');
        }
        $pageList = $this->handleSearch($query, $params)->paginate($params['per_page'] ?? 10);
        $data     = $this->resourceHandle->handleCollection($pageList);
        // 距离计算
        $data = $this->handleDistance($data, $params);
        return [$data, $this->generateMeta($pageList)];
    }

    /**
     * 商家详情
     * @param array $params
     * @return array
     */
    public function info(array $params): array
    {
        $shop = $this->model->with(['shopGoods' => function ($query) {
            $query->field('id,goods_id,shop_id,price')->with(['goods']);
        }])->find($params['id']);
        $shop = $this->resourceHandle->info($shop);
        return $this->handleDistance([$shop], $params)[0];
    }



    /**
     * 距离计算
     * @param $data
     * @param $params
     * @return array
     */
    public function handleDistance($data, $params): array
    {
        $toArr = [];
        foreach ($data as $datum) {
            $toArr[] = $datum['latitude'] . ',' . $datum['longitude'];
        }
        $toStr  = implode(';', $toArr);
        $req    = [
            'from' => $params['lat'] . ',' . $params['lng'],
            'to'   => $toStr
        ];
        $mapRes = TencentMap::instance()->matrix($req);
        if (isset($mapRes['rows'])) {
            foreach ($mapRes['rows'][0]['elements'] as $k => $ele) {
                $data[$k]['distance'] = number_format($ele['distance'] / 1000, 2, '.', '');
            }
        }
        return $data;
    }

    /**
     * 商家端-商家信息
     * @return mixed
     */
    public function shopInfo()
    {
        $shop = $this->model->find($this->shopId);
        $info = $this->resourceHandle->shopInfo($shop);
        $images = Images::where('shop_id',$this->shopId)->select();
        foreach ($images as $v){
            $info['images'][] = ['url'=>$v['image_url']];
        }
        $info['phone_arr'] = explode(',',$info['phone']);
        return $info;

    }

    /**
     * 商家端-更新营业时间
     * @param array $params
     * @return mixed
     * @throws ApiException
     */
    public function editBusinessTime(array $params = [])
    {
        if(Carbon::parse($params['business_start_time'])->gt(Carbon::parse($params['business_end_time']))) {
            throw new ApiException('营业开始时间不能大于结束时间',404);
        }
        $shop                      = $this->model->find($this->shopId);
        $shop->business_start_time = $params['business_start_time'] ?? '08:00';
        $shop->business_end_time   = $params['business_end_time'] ?? '20:00';
        return $shop->save();
    }

    /**
     * 商家标签列表
     * @return bool|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function tagList()
    {
        $shop = $this->model->find($this->shopId);
        $shopTags = explode(',',$shop->tags) ?? [];
        $tags = model('tag')->where('status', $this->enable)->order('sort desc')->select();
        foreach ($tags as $tag) {
            $tag->is_checked = 0;
            if (in_array($tag->id, $shopTags)) {
                $tag->is_checked = 1;
            }
            unset($tag['sort'],$tag['status'],$tag['createtime'],$tag['updatetime'],$tag['deletetime']);
        }
        return $tags;
    }

    /**
     * 保存商家标签
     * @param $params
     * @return false|\think\Model
     */
    public function saveTags($params)
    {
        // 过滤不存在标签
        $tagIds = model('tag')->where('status', $this->enable)->column('id');
        $tags = array_intersect($params['tags'], $tagIds);
        $this->getModel()->where('id', $this->shopId)->update(['tags' => implode(',',$tags)]);
        return true;
    }
}